package cn.itsource.ymcc.service.impl;

import cn.itsource.openfeign.EsCourseFeignClient;
import cn.itsource.ymcc.common.constant.RConst;
import cn.itsource.ymcc.common.result.JsonResult;
import cn.itsource.ymcc.domain.*;
import cn.itsource.ymcc.dto.AddCourseDto;
import cn.itsource.ymcc.mapper.CourseMapper;
import cn.itsource.ymcc.openfeign.MediaFeignClient;
import cn.itsource.ymcc.producer.CourseMessageProduce;
import cn.itsource.ymcc.service.*;
import cn.itsource.ymcc.vo.CourserDetailDataVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zcj
 * @since 2023-11-29
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private ICourseResourceService iCourseResourceService;
    @Autowired
    private ICourseDetailService iCourseDetailService;
    @Autowired
    private ICourseMarketService iCourseMarketService;
    @Autowired
    private ICourseSummaryService iCourseSummaryService;
    @Autowired
    private ICourseTypeService courseTypeService;
    @Autowired
    private EsCourseFeignClient esCourseFeignClient;
    @Autowired
    private ICourseCollectService iCourseCollectService;
    @Autowired
    private CourseMessageProduce courseMessageProduce;
    @Autowired
    private ICourseChapterService iCourseChapterService;
    @Autowired
    private MediaFeignClient mediaFeignClient;

    @Override
    public void save(AddCourseDto courseDto,Long currentId,String username) {
        //进行保存
        //保存主表
        Long courseId = saveCourse(courseDto,currentId,username);
        //保存资源表
        saveResource(courseId,courseDto);
        //保存详情表
        saveDetail(courseId,courseDto);
        //保存收费表
        saveMarket(courseId,courseDto);
        //初始化
        saveSummary(courseId);
    }

    private void saveSummary(Long courseId) {
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(courseId);
        courseSummary.setCommentCount(RConst.Num.INT_0);
        courseSummary.setSaleCount(RConst.Num.INT_0);
        courseSummary.setViewCount(RConst.Num.INT_0);
        iCourseSummaryService.save(courseSummary);
    }

    private void saveMarket(Long courseId, AddCourseDto courseDto) {
        CourseMarket courseMarket = new CourseMarket();
        BeanUtils.copyProperties(courseDto.getCourseMarket(),courseMarket);
        courseMarket.setId(courseId);
        iCourseMarketService.saveOrUpdate(courseMarket);
    }

    private void saveDetail(Long courseId, AddCourseDto courseDto) {
        CourseDetail courseDetail = new CourseDetail();
        BeanUtils.copyProperties(courseDto.getCourseDetail(),courseDetail);
        courseDetail.setId(courseId);
        iCourseDetailService.saveOrUpdate(courseDetail);
    }

    private void saveResource(Long courseId, AddCourseDto courseDto) {
        CourseResource courseResource = new CourseResource();
        BeanUtils.copyProperties(courseDto.getCourseResource(),courseResource);
        courseResource.setCourseId(courseId);
        iCourseResourceService.saveOrUpdate(courseResource);
    }

    private Long saveCourse(AddCourseDto courseDto,Long currentId,String username){
        Course course = new Course();
        BeanUtils.copyProperties(courseDto.getCourse(),course);
        course.setStatus(RConst.Num.INT_0);
        course.setLoginId(currentId);
        course.setLoginUserName(username);
//        course.getPic() 前端没有传
        course.setTotalMinute(RConst.Num.INT_0);//添加章节
        course.setChapterCount(RConst.Num.INT_0);//添加章节

        //保存老师名字
        List<Long> teacharIds = courseDto.getTeacharIds();
        LambdaQueryChainWrapper<Teacher> in = teacherService.lambdaQuery().in(Teacher::getId, teacharIds);
        List<Teacher> list = in.list();
        List<String> collect = list.stream().map(Teacher::getName).collect(Collectors.toList());
        course.setTeacherNames(String.join(",",collect));
        super.saveOrUpdate(course);
        courseMapper.deleteTeacherRelationship(course.getId());
        //保存老师的关系
        courseMapper.saveTeacherRelationship(teacharIds,course.getId());
        return course.getId();
    }
    @Override
    public void updateById(AddCourseDto courseDto,Long currentId,String username) {
        //进行修改
        //进行保存
        //保存主表
        Long courseId = saveCourse(courseDto,currentId,username);
        //保存资源表
        saveResource(courseId,courseDto);
        //保存详情表
        saveDetail(courseId,courseDto);
        //保存收费表
        saveMarket(courseId,courseDto);
    }

    //这个查询  要查询很多数据
    @Override
    public JsonResult courseInfo(Long id) {
        AddCourseDto courseDto = new AddCourseDto();
        //主表的数据
        Course course = super.baseMapper.selectById(id);
        courseDto.setCourse(course);
        //Market
        courseDto.setCourseMarket(iCourseMarketService.getById(id));
        //Resource
        courseDto.setCourseResource(iCourseResourceService.getOne(
                new LambdaQueryWrapper<CourseResource>().eq(CourseResource::getCourseId,id)));
        //Detail
        courseDto.setCourseDetail(iCourseDetailService.getById(id));
        //查询课程和老师的关系
        List<Long> teacherId = courseMapper.selectCourseTeacherRelationship(id);
        courseDto.setTeacharIds(teacherId);
        //课程类型
        courseDto.setCourseType(courseTypeService.getOne(new LambdaQueryWrapper<CourseType>().eq(CourseType::getId,course.getCourseTypeId())));
        return JsonResult.success().setData(courseDto);
    }

    //怎么样的数据才能上线
    @Override
    public JsonResult onLineCourse(List<Long> ids) {
        //从数据库里面去获取数据
        //判断用户选择的数据有没有上线
        // select * from t_course where status = 0 and (id in (1,2,3,4))
        LambdaQueryChainWrapper<Course> in = super.lambdaQuery().eq(Course::getStatus, RConst.Num.INT_0)
                .in(Course::getId,ids);
        List<Course> list = in.list();//这个里面就是那个用户选择且未上线的
        if(list.size() > 0){
            //修改数据值为上线
            list.forEach(course -> {
                course.setStatus(RConst.Num.INT_1);
                course.setOnlineTime(new Date());

                List<CourseCollect> list1 = iCourseCollectService.list(new LambdaQueryWrapper<CourseCollect>().eq(CourseCollect::getCourseId, course.getId()));
                for (CourseCollect courseCollect : list1) {
                    //你要给谁发
                    //发的内容是什么
                    Map<String,Object> message = new HashMap<>();
                    message.put("userId",courseCollect.getUserId());
                    message.put("content",course.getName()+"已上线，请去购买观看");
                    courseMessageProduce.sendEmail(JSON.toJSONString(message));
                    courseMessageProduce.sendSystem(JSON.toJSONString(message));
                    courseMessageProduce.sendSMS(JSON.toJSONString(message));
                }
            });
            //发起远程调用 es上线
            List<CourseDoc> courseDocList = buildCourseDoc(list);
            esCourseFeignClient.saveCourseToEs(courseDocList);

            super.updateBatchById(list);
        }
        //其中由一条上线 怎么处理  下线直接上  上线的的直接不管
        return JsonResult.success();
    }

    @Override
    public JsonResult getDetailData(Long courseId) {
        //第二种 去远程调用es服务 courseDoc 转换 返回前端
        //第一种 性能低 去数据库里面去查询
        //   我要查询什么数据
        //Map<String,Object> map = new HashMap<>();  //不太建议用，代码维护的复杂度
        CourserDetailDataVo courserDetailDataVo = new CourserDetailDataVo();
        courserDetailDataVo.setCourse(super.getById(courseId));
        courserDetailDataVo.setCourseSummary(iCourseSummaryService.getById(courseId));
        courserDetailDataVo.setCourseMarket(iCourseMarketService.getById(courseId));
        courserDetailDataVo.setCourseDetail(iCourseDetailService.getById(courseId));
        //老师
        List<Long> teacherIds = courseMapper.selectCourseTeacherRelationship(courseId);
        List<Teacher> teachers = teacherService.listByIds(teacherIds);
        courserDetailDataVo.setTeachers(teachers);
        //章节
        List<CourseChapter> courseChapterList = iCourseChapterService.list(new LambdaQueryWrapper<CourseChapter>()
                .eq(CourseChapter::getCourseId, courseId));

        courseChapterList.forEach(courseChapter -> {
            JsonResult list = mediaFeignClient.getList(courseChapter.getId());
            List<MediaFile> mediaFiles = JSONObject.parseArray(JSON.toJSONString(list.getData()), MediaFile.class);
            courseChapter.setMediaFiles(mediaFiles);
        });

        courserDetailDataVo.setCourseChapters(courseChapterList);
        return JsonResult.success().setData(courserDetailDataVo);
    }

    /**
     * 这个方法的作用就是帮我创造CourseDoc
     * @param list
     */
    private List<CourseDoc> buildCourseDoc(List<Course> list) {
        List<CourseDoc> courseDocList = new ArrayList<>();
        list.forEach(item->{
            CourseDoc courseDoc = new CourseDoc();
            BeanUtils.copyProperties(item,courseDoc);//BeanUtils.copyProperties 只能copy 相同属性 字段名和类型都要一致

            CourseType byId = courseTypeService.getById(item.getCourseTypeId());
            courseDoc.setCourseTypeName(byId.getName());

            courseDoc.setStartTime(item.getStartTime().getTime());
            courseDoc.setEndTime(item.getEndTime().getTime());

            courseDoc.setOnlineTime(item.getOnlineTime().getTime());
            //详情
            CourseDetail detail = iCourseDetailService.getById(item.getId());
            BeanUtils.copyProperties(detail,courseDoc);
            //收费规则
            CourseMarket market = iCourseMarketService.getById(item.getId());
            BeanUtils.copyProperties(market,courseDoc);
            courseDoc.setPrice(market.getPrice().doubleValue());
            courseDoc.setPriceOld(market.getPriceOld().doubleValue());
            //销量
            CourseSummary summary = iCourseSummaryService.getById(item.getId());
            if(summary != null){
                BeanUtils.copyProperties(summary,courseDoc);
            }
            //收藏
            int count = iCourseCollectService.count(new LambdaQueryWrapper<CourseCollect>().eq(CourseCollect::getCourseId, item.getId()));
            courseDoc.setCollectCount(count);

            courseDocList.add(courseDoc);
        });
        return courseDocList;
    }
}
